
# 导入所需的库
import os
import random

# 导入数据处理和可视化库
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 导入深度学习框架 PyTorch 相关库
import torch

from regex import F
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from torch import nn, optim
from torch.utils.data import TensorDataset, DataLoader
def setup_seed(seed=0):

    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed) if torch.cuda.is_available() else None

# 调用
setup_seed()

pd.set_option('display.max_columns', 1000)
pd.set_option('display.max_rows', 1000)
pd.set_option('display.width', 1000)

data = pd.read_csv('../dataset/train_V2.csv')
# print(data.head())


train_data = data.dropna(subset=['winPlacePerc'])
# print(train_data.isnull().sum())

count= data.groupby('matchId')['matchId'].transform('count')
# print(count)

train_data['count'] = count
new_data = train_data[ train_data["count"]==100]
print(len(new_data))

#划分特征和标签
x = new_data.drop(['matchId','Id','groupId'], axis=1)
y = new_data['winPlacePerc']
#对matchType进行独热编码
x_new = pd.get_dummies(x,columns=['matchType'])
# print(x_new.head())


x_train,x_test,y_train,y_test = train_test_split(
    x_new,  # 所有特征数据
    y,  # 所有标签数据
    test_size=0.2,  # 测试集占比（20% 数据作为测试集）
    shuffle=True  # 拆分前是否打乱数据（默认 True，推荐保持）
)
# print(x_train.shape, x_test.shape)

#数据标准化
scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train)
x_test_scaled = scaler.transform(x_test)

x_train_tensor = torch.tensor(x_train_scaled,dtype=torch.float32)
x_test_tensor = torch.tensor(x_test_scaled,dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1,1)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1,1)

#数据太多，分批次处理
train_dataset = TensorDataset(x_train_tensor, y_train_tensor)
dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)

#定义DNN
class  DNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(DNN, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.fc3 = nn.Linear(hidden_size, output_size)
        self.relu = nn.ReLU()
    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.fc3(x)
        return x

input_size = x_train.shape[1]
hidden_size = 128
output_size = 1
model = DNN(input_size, hidden_size, output_size)

#定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

epochs = 100
for epoch in range(1,1+epochs):
    model.train()
    total_loss = 0
    for inputs, labels in dataloader:
        optimizer.zero_grad()

        # 前向传播
        outputs = model(inputs)
        loss = criterion(outputs, labels)

        # 反向传播和优化
        loss.backward()
        optimizer.step()
        total_loss += loss.item()

    avg_loss = total_loss / len(dataloader)
    print(f'Epoch [{epoch + 1}/{epochs}], Loss: {avg_loss:.4f}')

with torch.no_grad():
    model.eval()
    test_value = model(x_test)
    loss = criterion(test_value, y_test)
    print(loss)
